
from importlib import reload
from datetime import datetime
from contextlib import contextmanager
from logging import DEBUG, StreamHandler, FileHandler

import dotfilebackup
from dotfilebackup.logger import log, add_log_file


# TODO: check if rollback of wrapped method is needed
@contextmanager
def sniff_console_outputs(logger) -> list[str]:
    '''
    ASSMUMPTION: LOGGER CONTAINS HANDLERS WITH DIFFERENT TYPES
    wrapps first logger.StreamHandler.format method with
    func capturing output returns list of log records
    '''
    def sniff(f, records):
        def sniffer(*a, **ka):
            output = f(*a, **ka)
            records.append(output)
            return output
        return sniffer

    records = []
    for handler in logger.handlers:
        original_format = handler.format
        handler.format = sniff(original_format, records)
        yield records
        # handler.format = original_format


class MESSAGE:
    D = 'debug-10'
    I = 'info-20'
    W = 'warning-30'
    E = 'error-40'
    C = 'critical-50'
    # L -> logged
    LD = 'DEBU: ' + D
    LI = 'INFO: ' + I
    LW = 'WARN: ' + W
    LE = 'ERRO: ' + E
    LC = 'CRIT: ' + C

def log_messages(logger):
    logger.debug(MESSAGE.D)
    logger.info(MESSAGE.I)
    logger.warning(MESSAGE.W)
    logger.error(MESSAGE.E)
    logger.critical(MESSAGE.C)


class TestLogger:
    def test_appropriate_messages_logged_to_console(self):
        with sniff_console_outputs(log) as console_rec:
            log_messages(log)
            assert len(console_rec) == 4
            assert MESSAGE.LI in console_rec[-4]
            assert MESSAGE.LW in console_rec[-3]
            assert MESSAGE.LE in console_rec[-2]
            assert MESSAGE.LC in console_rec[-1]

    def test_appropriate_messages_logged_to_file(self, tmp_path):
        file_name = 'dotfilebackup'
        log_file = tmp_path / (file_name + '.log')
        exp_datetime = str(datetime.now().astimezone())[:19]
        # str(...astimezone())      -> '2025-04-23 02:08:08.895923+02:00'
        # str(...astimezone())[:19] -> '2025-04-23 02:08:08'
        add_log_file(log, tmp_path, file_name)
        log_messages(log)
        with open(log_file) as f:
            lines = f.readlines()
            assert len(lines) == 5
            assert MESSAGE.LD in lines[-5]
            assert MESSAGE.LI in lines[-4]
            assert MESSAGE.LW in lines[-3]
            assert MESSAGE.LE in lines[-2]
            assert MESSAGE.LC in lines[-1]
            assert exp_datetime in lines[-5]
            assert exp_datetime in lines[-4]
            assert exp_datetime in lines[-3]
            assert exp_datetime in lines[-2]
            assert exp_datetime in lines[-1]

    def test_log_file_gets_overwritten_on_each_run(self, tmp_path):
        file_name = 'dotfilebackup'
        log_file = tmp_path / (file_name + '.log')
        add_log_file(log, tmp_path, file_name)
        log_messages(log)
        with open(log_file) as f:
            assert len(f.readlines()) == 5

        import logging
        reload(logging)
        reload(dotfilebackup.logger)
        from dotfilebackup.logger import log as log_2
        add_log_file(log_2, tmp_path, file_name)
        log_2.info('foobar')
        with open(log_file) as f:
            assert len(f.readlines()) == 1






#
